//
// Copyright (c) 2002-2010 "Neo Technology,"
//     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// This file is part of Neo4j.
// 
// Neo4j is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
using System.Collections.Generic;

namespace org.neo4j.graphdb
{
    /// <summary> 
    /// A traversal in the node space. A Traverser is an IEnumerable  that
    /// encapsulates a number of traversal parameters (defined at traverser creation)
    /// and returns an IEnumerator  of nodes that match those parameters. It is created
    /// by invoking <seealso cref="Node#traverse Node.traverse(...)"/>. Upon creation, the
    /// traverser is positioned at the start node, but it doesn't actually start
    /// traversing until its IEnumerator().Next()" method is invoked
    /// and will then traverse lazily one step each time {@code next} is called.
    /// 
    /// When a Traverser is created it is parameterized with two evaluators and the
    /// relationship types to traverse, with the direction to traverse each type in.
    /// The evaluators are used for determining for each node in the set of candidate
    /// nodes if it should be returned or not, and if the traversal should be pruned
    /// (stopped) at this point. The nodes that are traversed by a Traverser are each
    /// visited exactly once, meaning that the returned IEnumerator  of nodes will never
    /// contain duplicate nodes. This also means that the traversed relationships
    /// will form a spanning tree over the traversed nodes, with the side effect that
    /// some internal relationships between nodes in the traversal are not traversed
    /// (and hence not visible {@link TraversalPosition#lastRelationshipTraversed()
    /// in the evaluators}).
    /// 
    /// Typically a Traverser is used in a for-each loop as follows:
    /// 
    /// <pre>
    /// <code>
    /// Traverser friends = node.<seealso cref="Node#traverse(Traverser.Order, StopEvaluator, ReturnableEvaluator, RelationshipType, Direction) traverse"/>
    /// ( <seealso cref="Order#BREADTH_FIRST Order.BREADTH_FIRST"/>,
    ///<seealso cref="StopEvaluator#END_OF_GRAPH StopEvaluator.END_OF_GRAPH"/>,
    ///  <seealso cref="ReturnableEvaluator#ALL_BUT_START_NODE ReturnableEvaluator.ALL_BUT_START_NODE"/>,
    ///<seealso cref="RelationshipType MyRelationshipTypes.KNOWS"/>, <seealso cref="Direction#OUTGOING Direction.OUTGOING"/> );
    /// for ( <seealso cref="Node"/> friend : friends )
    /// {
    /// }
    /// </code>
    /// </pre>
    /// 
    /// Relationships are equally well traversed regardless of their direction,
    /// performance-wise.
    /// 
    /// For more usage examples please refer to the <a
    /// href="http://wiki.neo4j.org/content/Traversal">wiki documentation</a>.
    ///  </summary>
    /// <seealso cref= Node.traverse </seealso> 
	public interface Traverser : IEnumerable<Node>
    {
        #region Implementations

        ///<summary> 
        /// Returns the current traversal position, that is where the traversal is at
        ///the moment. It contains information such as which node we're at, which
        ///the last traversed relationship was (if any) and at which depth the
        ///current position is (relative to the starting node). You can use it in
        ///your traverser for-loop like this:
        ///
        ///<pre>
        ///<code>
        ///Traverser traverser = node.<seealso cref="Node#traverse traverse"/>( ... );
        ///for ( <seealso cref="Node"/> node : traverser )
        ///{
        ///    <seealso cref="TraversalPosition"/> currentPosition = traverser.currentPosition();
        ///    // Get "current position" information right here.
        ///}
        ///</code>
        ///</pre>
        /// </summary>
        ///<returns> The current traversal position </returns>
		TraversalPosition CurrentPosition();
        ///<summary> 
        /// Returns a collection of all nodes for this traversal. It traverses
        /// through the graph (according to given filters and evaluators) and
        /// collects those encountered nodes along the way. When this method has
        /// returned, this traverser will be at the end of its traversal, such that a
        /// call to {@code hasNext()} for the <seealso cref="IEnumerator "/> will return {@code
        /// false}.
        /// </summary>
        /// <returns> A collection of all nodes for this this traversal. </returns>   
		List<Node> GetAllNodes();
        /// <summary>
        /// Doc: does it create a new IEnumerator  or reuse the existing one? This is
        /// very important! It must be re-use, how else would currentPosition()
        /// make sense?
        /// </summary>
        /// <returns></returns>
		IEnumerable<Node> Iterator();

        #endregion
    }
}